/*
 * ioc.h
 *
 *  Created on: 21.11.2011
 *      Author: caiiiycuk
 */

#ifndef IOC_H_
#define IOC_H_

class IOCInternal;

template< typename T >
class IOC {
public:
	T*		 	 module;
	IOCInternal* internal;

	IOC(T* module): module(module), internal(0) { startup(module); }
	virtual ~IOC() { shutdown(); }

	void startup(T* module);
	void shutdown();

};

template<typename T>
class SUB {
private:
	T* sub;
public:
	SUB(T* sub): sub(sub) {
	}

	T* operator->() {
		return sub;
	}

	T& operator*() {
		return *sub;
	}
};

template <typename CLASS>
class PROVIDER {
public:
	typedef CLASS* pointer_type;
	typedef CLASS& ref_type;

	virtual ~PROVIDER() {};
	virtual pointer_type get() = 0;
};

template <typename CLASS>
class SINGLETON: public PROVIDER<CLASS> {
};

template <typename CLASS>
class DIRECT: public PROVIDER<CLASS> {
};

template <typename CLASS, typename PROVIDER>
class BIND {
public:
	BIND(PROVIDER* provider): provider(provider) {
	}

	BIND(const BIND<CLASS, PROVIDER>& copy): provider(copy.provider) {
	}

	~BIND() {
		//we don`t delete provider, cause
		//scope singleton.
		//provider will be deleted with concrete
		//module
	}

	typename PROVIDER::pointer_type operator->() {
		return provider->get();
	}

	typename PROVIDER::ref_type operator*() {
		return *provider->get();
	}

private:
	PROVIDER* provider;
};

template <typename CLASS>
class INSTANCE {
public:
	INSTANCE(): c(0) {}
	INSTANCE(CLASS* c): c(c) {}
	~INSTANCE() { delete c; }

	void set(CLASS* c) {
		this->c = c;
	}

	CLASS* get() {
		return c;
	}
private:
	INSTANCE(const INSTANCE&);
	INSTANCE& operator =(const INSTANCE& b);

	CLASS* c;
};


#endif /* IOC_H_ */
